
#ifndef NOSAL_EXEC_INTERNAL_CONFIG_EXECUTION_MANIFEST_H_
#define NOSAL_EXEC_INTERNAL_CONFIG_EXECUTION_MANIFEST_H_

#include <chrono>
#include <cstdint>

#include "config/startup_configuration.h"

#include "nosal/log/logger.h"
#include "nosal/core/optional.h"

namespace netaos {
namespace nosal {
namespace exec {
namespace internal {
namespace config {

/// @brief Execution Manifest.
class ExecutionManifest final
{
public:
    /**
     * @brief ExecutionStateReportingBehavior represents the enumeration
     *        ExecutionStateReportingBehaviorEnum in the Meta Model
     */
    enum class ExecutionStateReportingBehavior
    {
        kReports = 0,
        kDoesNotReport = 1
    };

    ExecutionManifest(std::string manifest_path, const EnterExitTimeout& default_timeout);

    bool IsPlatformApplication() const
    {
        return is_platform_application_;
    }

    /// @brief Get the Process Name
    ///
    /// @return Name of the process according to the ProcessName Entry
    ///         or nullopt if not set
    const nosal::core::Optional<std::string>& GetProcessName() const
    {
        return process_name_;
    }

    const std::chrono::nanoseconds& GetTimerResolution() const
    {
        return timer_resolution_;
    }
    const std::vector<StartupConfiguration>& GetStartupConfigs() const
    {
        return startup_configs_;
    }

    ExecutionStateReportingBehavior GetReportingBehavior() const
    {
        return reporting_behavior_;
    }

    const std::string& GetFunctionClusterAffiliation() const
    {
        return function_cluster_affiliation_;
    }

    std::uint32_t GetNumberOfRestartAttempts() const
    {
        return number_of_restart_attempts_;
    }

    std::uint32_t GetCrc32Value() const noexcept
    {
        return crc32_value_;
    }

    const nosal::core::Optional<std::string> GetExecutableVersion() const noexcept
    {
        return executable_version_;
    }

    /// @brief Return list of cores that the process shall run on.
    const std::vector<std::uint32_t> GetCoreAffinityShallRunOn() const noexcept
    {
        return shall_run_on_;
    }

    /// @brief Return list of cores that the process shall not run on.
    const std::vector<std::uint32_t> GetCoreAffinityShallNotRunOn() const noexcept
    {
        return shall_not_run_on_;
    }

private:
    ExecutionStateReportingBehavior ParseReportingBehavior(const std::string& value) const;

    std::uint32_t CalculateCrc32Value(std::string file_path);

    bool is_platform_application_;
    std::chrono::nanoseconds timer_resolution_;
    std::vector<StartupConfiguration> startup_configs_;
    ExecutionStateReportingBehavior reporting_behavior_;
    nosal::core::Optional<std::string> process_name_;
    std::string function_cluster_affiliation_;
    std::uint32_t number_of_restart_attempts_;
    std::uint32_t crc32_value_;
    nosal::core::Optional<std::string> executable_version_;

    /// @brief List of cores where a process shall run on.
    std::vector<std::uint32_t> shall_run_on_;

    /// @brief List of cores where a process shall not run on.
    std::vector<std::uint32_t> shall_not_run_on_;
};

} // namespace config
} // namespace internal
} // namespace exec
} // namespace nosal
} // namespace netaos

#endif  // NOSAL_EXEC_INTERNAL_CONFIG_EXECUTION_MANIFEST_H_
